package com.wstuo.itsm.knowledge.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.json.JSONException;
import org.apache.struts2.json.JSONUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.wstuo.common.Luence.LuenceUtil;
import com.wstuo.common.config.attachment.dao.IAttachmentDAO;
import com.wstuo.common.config.attachment.entity.Attachment;
import com.wstuo.common.config.attachment.service.IAttachmentService;
import com.wstuo.common.config.category.dao.IEventCategoryDAO;
import com.wstuo.common.config.category.dto.EventCategoryDTO;
import com.wstuo.common.config.category.entity.EventCategory;
import com.wstuo.common.config.category.service.IEventCategoryService;
import com.wstuo.common.config.comment.dao.ICommentDAO;
import com.wstuo.common.config.comment.entity.Comment;
import com.wstuo.common.config.customfilter.dao.IFilterDAO;
import com.wstuo.common.config.customfilter.dto.KeyTransferDTO;
import com.wstuo.common.config.customfilter.entity.CustomFilter;
import com.wstuo.common.config.customfilter.service.ILinksEventQueryServices;
import com.wstuo.common.config.historyData.dto.HistoryDataDTO;
import com.wstuo.common.config.historyData.service.IHistoryDataService;
import com.wstuo.common.exportmq.ExportMessageProducer;
import com.wstuo.common.tools.dto.ExportQueryDTO;
import com.wstuo.common.tools.entity.ExportInfo;
import com.wstuo.common.tools.service.IExportInfoService;
import com.wstuo.itsm.knowledge.dao.IKnowledgeDAO;
import com.wstuo.itsm.knowledge.dto.CommentDTO;
import com.wstuo.itsm.knowledge.dto.KnowledgeCountResultDTO;
import com.wstuo.itsm.knowledge.dto.KnowledgeDTO;
import com.wstuo.itsm.knowledge.dto.KnowledgeQueryDTO;
import com.wstuo.itsm.knowledge.entity.KnowledgeInfo;
import com.wstuo.common.dto.PageDTO;
import com.wstuo.common.exception.ApplicationException;
import com.wstuo.common.file.csv.CSVReader;
import com.wstuo.common.security.dao.IUserDAO;
import com.wstuo.common.security.entity.User;
import com.wstuo.common.security.service.IUserInfoService;
import com.wstuo.common.security.utils.AppConfigUtils;
import com.wstuo.common.security.utils.AppContext;
import com.wstuo.common.security.utils.FileEncodeUtils;
import com.wstuo.common.security.utils.LanguageContent;
import com.wstuo.common.util.StringUtils;
import com.wstuo.common.util.TimeUtils;

/**
 * 知识库业务类.
 * 
 * @author QXY
 */
public class KnowledgeService implements IKnowledgeService {
	final static Logger LOGGER = Logger.getLogger(KnowledgeService.class);
	@Autowired
	private IKnowledgeDAO knowledgeDAO;
	@Autowired
	private IAttachmentService attachmentService;
	@Autowired
	private IUserInfoService userInfoService;
	@Autowired
	private IHistoryDataService historyDataService;
	@Autowired
	private IUserDAO userDAO;
	@Autowired
	private IAttachmentDAO attachmentDAO;
	@Autowired
	private IExportInfoService exportInfoService;
	@Autowired
	private ExportMessageProducer exportMessageProducer;
	@Autowired
	private IEventCategoryDAO eventCategoryDAO;
	@Autowired
	private ILinksEventQueryServices linksEventQueryServices;
	@Autowired
	private AppContext appctx;
	@Autowired
	private IEventCategoryService eventCategoryService;
	@Autowired
	private IFilterDAO filterDAO;
	
	@Autowired
	private ICommentDAO commentDAO;
	
	/**
	 * 分页查找知识信息.
	 * 
	 * @param dto 查询DTO
	 * @param start 起始行
	 * @param limit 结束行
	 * @return PageDTO 分页数据
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public PageDTO findKnowledgesByPages(KnowledgeQueryDTO dto, int start,int limit, String sidx, String sord) {
		PageDTO pageDto = new PageDTO();
		String loginUserName = "";
		if(!StringUtils.hasLength(dto.getLoginUserName())){
			loginUserName=appctx.getCurrentLoginName();
		}else{
			loginUserName=dto.getLoginUserName();
		}
		if (dto.getOpt() != null&& (dto.getOpt().equals("my") || "myap".equals(dto.getOpt()) || "myapf".equals(dto.getOpt()))) {
			dto.setCreatorName(loginUserName);
		}
		if (dto.getEventId()!=null) {
			Long[] allSubCategoryIds = eventCategoryService.findSubCategoryIdsByEventId(dto.getEventId());
			Long[] ableCategoryIds = userInfoService.findCategoryNosByLoginName(loginUserName, "Knowledge_Category_");
			if(ableCategoryIds!=null){
				List<Long> categoryIds = (List<Long>) CollectionUtils.intersection(Arrays.asList(allSubCategoryIds), Arrays.asList(ableCategoryIds));
				//根据ID查看所有子节点
				dto.setEventIds(categoryIds.toArray(new Long[categoryIds.size()]));
			}else{
				//根据ID查看所有子节点
				dto.setEventIds(null);
			}
		}else{
			//设置查看权限(分类权限)
			dto.setEventIds(userInfoService.findCategoryNosByLoginName(loginUserName, "Knowledge_Category_"));
		}
		
		pageDto = knowledgeDAO.findAllKnowledgeInfos(dto, start, limit ,sidx, sord);
		List<KnowledgeInfo> entitys = pageDto.getData();
		List<KnowledgeDTO> dtos = new ArrayList<KnowledgeDTO>(
				entitys.size());
		User user = userDAO.findUniqueBy("loginName",loginUserName);
		for (KnowledgeInfo entity : entitys) {
			KnowledgeDTO knowledgeDTO = new KnowledgeDTO();
			if (entity.getCreate() == null) {
				if (StringUtils.hasText(entity.getCreatorFullName())) {
					user = userDAO.findUniqueBy("loginName",
							entity.getCreator());
					entity.setCreate(user);
				} else if(user!=null&&user.getFullName()!=null){
					entity.setCreatorFullName(user.getFullName());
					entity.setCreate(user);
				}
				knowledgeDAO.save(entity);
			}
			knowledgeDTO.entity2dto(entity, knowledgeDTO);
			List<EventCategory> ecs = entity.getServiceLists();
			if (ecs != null && ecs.size() > 0) {
				StringBuffer strBu = new StringBuffer();
				for (EventCategory ec : ecs) {
					strBu.append(ec.getEventName() + ",");
				}
				String strName = strBu.toString();
				knowledgeDTO.setKnowledgeServiceName(strName.substring(0,
						strName.length() - 1));
			}
			if (entity.getCreate() != null) {
				knowledgeDTO.setCreatorFullName(entity.getCreate()
						.getFullName());
			}
			dtos.add(knowledgeDTO);
		}
		pageDto.setData(dtos);
		return pageDto;
	}

	/**
	 * 自定义分页查询知识库列表.
	 * @param qdto 包含查询条件
	 * @return PageDTO
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public PageDTO findKnowledgesPagerByCustomtFilter(KnowledgeQueryDTO qdto,
			String sidx, String sord) {
		CustomFilter filter = filterDAO.findById(qdto.getFilterId());
		if (filter == null) {
			throw new ApplicationException("ERROR_FILTER_NOT_EXISTS");
		} else {
			List<Object> liid=knowledgeDAO.findByServiceDirectoryFilter(filter);
			List<Long> lis=new ArrayList<Long>(); 
			if(liid!=null){
				for (Object obj : liid) {
					if(((Map) obj).get("kid")!=null){
						lis.add(Long.parseLong(((Map) obj).get("kid").toString()));
					}
					if(((Map) obj).get("KID")!=null){
						lis.add(Long.parseLong(((Map) obj).get("KID").toString()));
					}
				}
			}
			KnowledgeQueryDTO queryDTO = new KnowledgeQueryDTO();
			List<Long> list = viewCategorys();//指定查询分类权限
			if (list != null) {
				queryDTO.setCategoryIds( list.toArray(new Long[list.size()]) );
			}
			PageDTO pageDTO = knowledgeDAO.findPageByCustomFilter(filter, queryDTO,lis, qdto.getStart(), qdto.getLimit(), sidx, sord);
			if(pageDTO!=null){
				List<KnowledgeInfo> entitys = (List<KnowledgeInfo>) pageDTO.getData();
				if(entitys!=null && entitys.size()>0){
					List<KnowledgeDTO> dtos = new ArrayList<KnowledgeDTO>(entitys.size());
					for (KnowledgeInfo entity : entitys) {
						KnowledgeDTO knowledgeDto = new KnowledgeDTO();
						knowledgeDto.entity2dto(entity, knowledgeDto);
						List<EventCategory> ecs = entity.getServiceLists();
						if (ecs != null && ecs.size() > 0) {
							StringBuffer strBu = new StringBuffer();
							for (EventCategory ec : ecs) {
								strBu.append(ec.getEventName() + ",");
							}
							String strName = strBu.toString();
							knowledgeDto.setKnowledgeServiceName(strName.substring(0,
									strName.length() - 1));
						}
						dtos.add(knowledgeDto);
					}
					pageDTO.setData(dtos);
				}
				
			}
			return pageDTO;
		}
	}

	/**
	 * 查找最新或最热知识
	 * @param queryType 最新或最热标识
	 * @param loginName 登录用户名
	 * @return List<KnowledgeDTO> 
	 */
	private List<KnowledgeDTO> findForPortal(String queryType, String loginName) {
		Long[] categoryIds = userInfoService.findCategoryNosByLoginName(loginName,
				"Knowledge_Category_");// 设置查看权限
		List<KnowledgeDTO> dtos = new ArrayList<KnowledgeDTO>();
		if (categoryIds != null && categoryIds.length > 0) {

			List<KnowledgeInfo> entitys = knowledgeDAO.findKnowledgeByIds(
					queryType, categoryIds);
			dtos = new ArrayList<KnowledgeDTO>(entitys.size());

			for (KnowledgeInfo entity : entitys) {
				KnowledgeDTO dto = new KnowledgeDTO();
				dto.entity2dto(entity, dto);
				dtos.add(dto);
			}
		}
		return dtos;
	}

	/**
	 *查找最新知识.
	 * @return List<KnowledgeDTO> 最新知识集合.
	 */
	@Transactional
	public List<KnowledgeDTO> findNewKnowledge(String loginName) {
		return findForPortal("new", loginName);

	}

	/**
	 * 查找热门知识.
	 * 
	 * @return List<KnowledgeDTO> 热门知识集合.
	 */
	@Transactional
	public List<KnowledgeDTO> findPopularKnowledge(String loginName) {

		return findForPortal("pop", loginName);
	}

	/**
	 * 根据ID查找知识信息.
	 * 
	 * @param id 知识库编号
	 * @return KnowledgeDTO 知识库DTO类
	 */
	@Transactional
	public KnowledgeDTO findById(Long id) {

		KnowledgeInfo entity = knowledgeDAO.findById(id);
		KnowledgeDTO dto = new KnowledgeDTO();
		
		if(entity!=null){
			entity.setClickRate(entity.getClickRate() + 1);
	
			EventCategory category = entity.getCategory();
	
			if (category != null) {
				dto.setCategoryName(category.getEventName());
				dto.setCategoryNo(category.getEventId());
	
				List<EventCategory> li = entity.getServiceLists();
				List<EventCategoryDTO> listEvent = new ArrayList<EventCategoryDTO>();
	
				if (li != null && li.size() > 0) {
					for (EventCategory ev : li) {
						EventCategoryDTO evDto = new EventCategoryDTO();
						evDto.setEventId(ev.getEventId());
						evDto.setEventName(ev.getEventName());
						listEvent.add(evDto);
					}
					dto.setListEvent(listEvent);
				}
	
			}
	
			List<Attachment> attrs = entity.getAttachements();
	
			if (attrs != null && attrs.size() > 0) {
				dto.setAttachments(attrs);
			}
	
			dto.entity2dto(entity, dto);
	
			if (entity.getCategory() != null) {
				dto.setCategoryName(entity.getCategory().getEventName());
			}

		}
		return dto;
	}

	/**
	 * DTO转实体
	 * @param dto
	 * @param entity
	 */
	private void dto2entity(KnowledgeDTO dto, KnowledgeInfo entity) {
		// 转换普通字段
		KnowledgeDTO.dto2entity(dto, entity);
		// 分类
		if (dto.getCategoryNo() != null) {
			EventCategory category = eventCategoryDAO.findById(dto.getCategoryNo());
			entity.setCategory(category);
		} else {
			EventCategory category = eventCategoryDAO.findUniqueBy("categoryRoot",
					"Knowledge");
			entity.setCategory(category);
		}
		// 保存附件
		if (dto.getAttachmentStr() != null) {
			List<Attachment> attrs = attachmentService.saveAttachment(
					dto.getAttachmentStr(), "itsm.knowledge");
			// Antony 20120801
			if (dto.getAids() != null) {
				if (attrs == null)
					attrs = new ArrayList<Attachment>();
				for (Long aid : dto.getAids()) {
					Attachment at = attachmentDAO.findById(aid);
					attrs.add(at);
				}
			}
			if (entity.getAttachements() == null) {
				List<Attachment> attachments = new ArrayList<Attachment>();
				entity.setAttachements(attachments);
			}
			entity.getAttachements().addAll(attrs);
		}
		if (dto.getKnowledServiceNo() != null
				&& dto.getKnowledServiceNo().size() > 0) {
			List<EventCategory> li = new ArrayList<EventCategory>();
			for (Long id : dto.getKnowledServiceNo()) {
				li.add(eventCategoryDAO.findById(id));
			}
			entity.setServiceLists(li);
		}

	}

	/**
	 * 修改知识库信息.
	 * @param dto  知识库DTO类
	 */
	@Transactional
	public void updateKnowledgeInfo(KnowledgeDTO dto) {

		KnowledgeInfo entity = knowledgeDAO.findById(dto.getKid());

		
		String creator = entity.getCreator();
		String fullName = null;
		if (entity.getCreate() != null) {
			fullName = entity.getCreate().getFullName();
		} else {
			fullName = entity.getCreatorFullName();
		}
		Long click = entity.getClickRate();
		dto2entity(dto, entity);
		//String status = entity.getKnowledgeStatus();
		/*if (status.equals("-1")) {// 审核失败的
			entity.setKnowledgeStatus("0");
		} else {
			entity.setKnowledgeStatus(status);

		}*/
		entity.setClickRate(click);
		entity.setCreator(creator);
		entity.setCreatorFullName(fullName);
		entity.setLastUpdateTime(new Date());
		entity.setCreate(entity.getCreate());

		knowledgeDAO.update(entity);
		Map<String, String> map =new HashMap<String, String>();
		map.put("id", entity.getKid()+"");
		map.put("title", entity.getTitle());
		map.put("keyWords", entity.getKeyWords());
		map.put("content", entity.getContent());
		LuenceUtil.getInstance(MODULECATEGORY).update(map);
	}

	/**
	 * 保存知识信息.
	 * @param dto 知识库DTO类
	 */
	@Transactional
	public void saveKnowledgeInfo(KnowledgeDTO dto) {
		 
		
    	if(StringUtils.hasText(dto.getCreator())){
    		dto.setCreator(appctx.getCurrentLoginName());
    	}
		KnowledgeInfo entity = new KnowledgeInfo();
		dto2entity(dto, entity);
		if (dto.getCreator() != null) {
			User user = userDAO.findUniqueBy("loginName", dto.getCreator());
			if (user != null) {
				entity.setCreatorFullName(user.getFullName());
				entity.setCreate(user);
			}
		}
		if (dto.getKnowledgeStatus() == null) {// 默认需要审核
			entity.setKnowledgeStatus("0");
		}
		knowledgeDAO.save(entity);
		dto.setKid(entity.getKid());
		Map<String, String> map =new HashMap<String, String>();
		map.put("id", entity.getKid()+"");
		map.put("title", entity.getTitle());
		map.put("keyWords", entity.getKeyWords());
		map.put("content", entity.getContent());
		LuenceUtil.getInstance(MODULECATEGORY).add(map);
	}

	/**
	 * 删除附件.
	 * 
	 * @param kid 知识编号.
	 * @param aid 附件编号.
	 */
	@Transactional
	public void deleteAttachment(Long kid, Long aid) {
		KnowledgeInfo knowledge = knowledgeDAO.findById(kid);
		if (knowledge != null) {
			List<Attachment> attrs = knowledge.getAttachements();
			if (attrs != null && attrs.size() > 0) {
				for (Attachment a : attrs) {
					if (a.getAid().equals(aid)) {
						knowledge.getAttachements().remove(a);
						break;
					}
				}
			}
		}
	}

	/**
	 * 保存历史数据.
	 * 
	 * @param nos 知识库编号数组
	 */
	private void saveHistoryData(Long[] nos) {

		// 备份数据
		if (nos != null && nos.length > 0) {
			for (Long id : nos) {
				try {
					KnowledgeInfo kif = knowledgeDAO.findById(id);
					KnowledgeDTO dto = new KnowledgeDTO();
					dto.entity2dto(kif, dto);
					HistoryDataDTO historyDataDTO = new HistoryDataDTO(id,
							MODULECATEGORY, dto.getTitle(),
							JSONUtil.serialize(dto));
					historyDataService.saveHistoryData(historyDataDTO);

				} catch (JSONException e) {
					throw new ApplicationException(
							"ERROR_CONVERT_DTO_TO_JSON/n" + e.getMessage(), e);
				}
			}
		}
	}

	/**
	 * 删除知识库信息.
	 * 
	 * @param nos 知识编号数组.
	 */
	@Transactional
	public void removeKnowledgeItems(Long[] nos) {

		saveHistoryData(nos);// 保存历史数据
		knowledgeDAO.deleteByIds(nos);// 删除数据
		for (Long long1 : nos) {
			LuenceUtil.getInstance(MODULECATEGORY).delete(long1);
		}
	}

	/**
	 * 导出数据方法
	 */
	@Transactional
	public void exportKnowledges(ExportQueryDTO exportQueryDTO) {
		try {
			KnowledgeQueryDTO dto=(KnowledgeQueryDTO) exportQueryDTO.getQueryDTO();
			List<KnowledgeInfo> datas = null;
			if(dto!=null && dto.getFilterId()!=null){
				CustomFilter filter= filterDAO.findById(dto.getFilterId());
				List<Object> liid=knowledgeDAO.findByServiceDirectoryFilter(filter);
				List<Long> lis=new ArrayList<Long>(); 
				if(liid!=null){
					for (Object obj : liid) {
						if(((Map) obj).get("kid")!=null){
							lis.add(Long.parseLong(((Map) obj).get("kid").toString()));
						}
						if(((Map) obj).get("KID")!=null){
							lis.add(Long.parseLong(((Map) obj).get("KID").toString()));
						}
					}
				}
				datas=knowledgeDAO.findListByCustomFilter(filter, null,lis, dto.getSidx(), dto.getSord());
				
			}else if(dto!=null && StringUtils.hasText(dto.getAlias())) {
				fullTextSearch(dto);
				if(dto.getKids()!=null && dto.getKids().length>0)
					datas = knowledgeDAO.findListKnowledgeInfos(dto,dto.getSidx(), dto.getSord());
			}else if(dto!=null){
				datas = knowledgeDAO.findListKnowledgeInfos(dto,dto.getSidx(), dto.getSord());
			}
			List<String[]> data = new ArrayList<String[]>();
			LanguageContent lc = LanguageContent.getInstance();
			data.add(new String[] { lc.getContent("common.title", dto.getLang()),
					lc.getContent("common.content", dto.getLang()),
					lc.getContent("common.category", dto.getLang()),
					lc.getContent("label.knowledge.relatedService", dto.getLang()),
					lc.getContent("common.cerateTime", dto.getLang()),
					lc.getContent("label.keywords", dto.getLang()) });
			if (datas!= null && datas.size() > 0) {
				if(dto != null){
					String categoryName = "";
					
					for (KnowledgeInfo item : datas) {
						String serviceName = "";
						if (item.getCategory() != null) {
							EventCategory ec = eventCategoryDAO.findById(item
									.getCategory().getEventId());
							categoryName = ec.getEventName() + "";
						}
						if (item.getServiceLists() != null && item.getServiceLists().size() > 0) {
							String sname="";
							for (EventCategory ec : item.getServiceLists()) {
								sname = sname + "," + ec.getEventName();
							}
							serviceName=sname.substring(1);
						}
						data.add(new String[] { item.getTitle(),
								StringUtils.stripHtml(item.getContent()), categoryName,
								serviceName, TimeUtils.format(item.getAddTime(),TimeUtils.DATETIME_PATTERN),
								item.getKeyWords() });
					}
					
				}
			}
			if(StringUtils.hasText(exportQueryDTO.getPath())){
				ExportInfo entity = new ExportInfo();
				entity = dto.getEntity();
				entity.setTanentId(appctx.getCurrentTenantId());
				exportInfoService.exportCommonCSV(data,entity,exportQueryDTO.getPath());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 导出搜索出来的知识
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public void exportFindData(KnowledgeQueryDTO dto, String sidx, String sord) {
		ExportInfo entity = exportInfoService.saveExportInfoReturnEntity("Knowledge");
		String loginUserName = "";
		if(!StringUtils.hasLength(dto.getLoginUserName())){
			loginUserName=appctx.getCurrentLoginName();
		}else{
			loginUserName=dto.getLoginUserName();
		}
		if (dto.getOpt() != null&& (dto.getOpt().equals("my") || "myap".equals(dto.getOpt()) || "myapf".equals(dto.getOpt()))) {
			dto.setCreatorName(loginUserName);
		}
		
		if (dto.getEventId()!=null) {
			Long[] allSubCategoryIds = eventCategoryService.findSubCategoryIdsByEventId(dto.getEventId());
			Long[] ableCategoryIds = userInfoService.findCategoryNosByLoginName(loginUserName, "Knowledge_Category_");
			if(ableCategoryIds!=null){
				List<Long> categoryIds = (List<Long>) CollectionUtils.intersection(Arrays.asList(allSubCategoryIds), Arrays.asList(ableCategoryIds));
				//根据ID查看所有子节点
				dto.setEventIds(categoryIds.toArray(new Long[categoryIds.size()]));
			}else{
				//根据ID查看所有子节点
				dto.setEventIds(null);
			}
		}else{
			//设置查看权限(分类权限)
			dto.setEventIds(userInfoService.findCategoryNosByLoginName(loginUserName, "Knowledge_Category_"));
		}
		dto.setSidx(sidx);
		dto.setSord(sord);
		String lang = appctx.getCurrentLanguage();
		dto.setLang(lang);
		dto.setFileFormat(dto.getFileFormat());
		dto.setEntity(entity);
		
		ExportQueryDTO exportQueryDTO=new ExportQueryDTO();
		exportQueryDTO.setTenantId(appctx.getCurrentTenantId());
		exportQueryDTO.setQueryDTO(dto);
		exportQueryDTO.setType(FILTERCATEGORY);
		String path = AppConfigUtils.getInstance().getConfigPathByTenantId(
				"exportFilePath", "exportFile", appctx.getCurrentTenantId());
		exportQueryDTO.setPath(path);
		
		exportMessageProducer.send(exportQueryDTO);
	}

	/*@Transactional
	public void exportFindDataFind(FullTextQueryDTO<KnowledgeInfo> queryDTO) {
		queryDTO.setLoginName(appctx.getCurrentLoginName());
		ExportInfo entity = exportInfoService.saveExportInfoReturnEntity("Knowledge");
		KnowledgeQueryDTO dto=new KnowledgeQueryDTO();
		dto.setFullTextDTO(queryDTO);
		dto.setLang(appctx.getCurrentLanguage());
		dto.setFileFormat(dto.getFileFormat());
		dto.setEntity(entity);

		ExportQueryDTO exportQueryDTO=new ExportQueryDTO();
		exportQueryDTO.setTenantId(appctx.getCurrentTenantId());
		exportQueryDTO.setQueryDTO(dto);
		exportQueryDTO.setType(FILTERCATEGORY);
		String path = AppConfigUtils.getInstance().getConfigPathByTenantId(
				"exportFilePath", "exportFile", appctx.getCurrentTenantId());
		exportQueryDTO.setPath(path);
		
		exportMessageProducer.send(exportQueryDTO);
		
	}*/

	/**
	 * 导入数据方法.
	 * @param importFile 导入文件路径
	 * @return String 导入结果
	 */
	@Transactional
	public String importKnowledge(File importFile) {

        int insert = 0; // 新增
        int update = 0; // 更新
        int failure = 0;// 失败
        int total = 0;  // 总数
        
        Reader rd = null;
        CSVReader reader = null;
        
        
        try {
			String fileEncode = FileEncodeUtils.getFileEncode(importFile);
			rd = new InputStreamReader(new FileInputStream(importFile), fileEncode);// 以字节流方式读取数据
            reader = new CSVReader(rd);
            String[] line = null;
            String title = "";
            boolean bool = true;// 记录标题是否已存在
            while ((line = reader.readNext()) != null) {
            	//标题
                title = line[0].toString();
                KnowledgeInfo entity = knowledgeDAO.findUniqueBy("title", title);
                total++;
                if (entity == null) { // 判断标题是否存在
                   
                    entity = new KnowledgeInfo();
                    entity.setCompanyNo(1L);
                    entity.setTitle(title);
                    //添加时间
                    if (StringUtils.hasText(line[4])) {
                        String str = line[4].toString();
                        str = str.replace("/", "-");
                        entity.setAddTime(TimeUtils.parse(str,TimeUtils.DATETIME_PATTERN));
                        entity.setLastUpdateTime(TimeUtils.parse(str,TimeUtils.DATETIME_PATTERN));
                    } else {
                        entity.setAddTime(new Date());
                    }
                    bool = false;
                }
                //内容
                entity.setContent(line[1].toString());
                //分类
                if (!line[2].toString().equals("")) {
                    EventCategory ec = eventCategoryDAO.findUniqueBy("eventName", line[2].toString());
                    if (ec != null) {
                        entity.setCategory(ec);
                    } else {
                    	EventCategoryDTO ecDTO=new EventCategoryDTO();
                    	ecDTO.setEventName(line[2].toString());
                    	ecDTO.setParentEventId(eventCategoryDAO.findBy("categoryRoot", "Knowledge").get(0).getEventId());
                        entity.setCategory(eventCategoryService.saveEventCategory(ecDTO));
                    }
                } else {
                    EventCategory ec = eventCategoryDAO.findBy("categoryRoot", "Knowledge").get(0);
                    entity.setCategory(ec);
                }
                //服务目录
                if (!line[3].toString().equals("")) {
                    List<EventCategory> li = new ArrayList<EventCategory>();
                    String[] servicesName = line[3].toString().split(",");
                    EventCategory parentEvent = eventCategoryDAO.findUniqueBy("categoryRoot", "Service");
                    for (String serviceName : servicesName) {
                        EventCategory ec = eventCategoryDAO.findUniqueBy(
                                "eventName", serviceName);
                        if (ec != null) {
                            li.add(ec);
                        } else {
                            EventCategory ecg = new EventCategory();
                            ecg.setEventName(line[3].toString());
                            ecg.setParentEvent(parentEvent);
                            ecg.setCompanyNo(1L);
                            ecg.setDataFlag(Byte.parseByte("0"));
                            eventCategoryDAO.save(ecg);
                            li.add(ecg);
                        }
                    }
                    entity.setServiceLists(li);
                }
                //关键字
                if (!line[5].toString().equals("")) {
                    entity.setKeyWords(line[5].toString());
                }
                entity.setKnowledgeStatus("1");
                
                // 判断模板中的用户是否存在，不存在用当前登录用户，当前没有登录用户用admin
                User user = userDAO.findUniqueBy("fullName",line[6]);
                if (user == null) {
                    user = userDAO.findUniqueBy("loginName", appctx.getCurrentLoginName());
                }
                if (user == null) {
                    entity.setCreator("admin");
                    user = userDAO.findUniqueBy("loginName", entity.getCreator());
                }
                if (user != null) {
	                entity.setCreator(user.getLoginName());
	                entity.setCreate(user);
	                entity.setCreatorFullName(user.getFullName());
                }
                if (!bool) { // 判断标题是否存在
                    knowledgeDAO.save(entity);
                    bool = true;
                    insert++;
                } else {
                    // 最后更新时间
                    entity.setLastUpdateTime(new Date());
                    knowledgeDAO.merge(entity);
                    update++;
                }
                
            }
        } catch (UnsupportedEncodingException e) {
        	failure++;
            LOGGER.error("导入知识库数据异常" + e);
        } catch (FileNotFoundException e) {
        	failure++;
            throw new ApplicationException("ERROR_CSV_FILE_NOT_EXISTS\n" + e, e);
        } catch (IOException e) {
        	failure++;
            throw new ApplicationException("ERROR_CSV_FILE_IO\n" + e, e);
        }  catch (Exception e) {
        	e.printStackTrace();
        	failure++;
           LOGGER.error("导入知识库数据异常" + e);
        } finally {
            try {
                if (rd != null)
                    rd.close();
                if (reader != null)
                    reader.close();
                
            } catch (IOException e) {
            	LOGGER.error(e);
            }
        }
        return "Total:" + total 
                + ",&nbsp;Insert:" + insert
                + ",&nbsp;Update:" + update
                + ",&nbsp;Failure:" + failure;
         
	}


	/**
	 * 恢复数据.
	 */
	@Transactional
	public void restoreData(Long[] historyDataNos) {
		if (historyDataNos != null && historyDataNos.length > 0) {
			for (Long id : historyDataNos) {
				KnowledgeDTO dto = (KnowledgeDTO) historyDataService.restore(
						id, "com.wstuo.itsm.knowledge.dto.KnowledgeDTO");// 取得DTO
				KnowledgeInfo entity = new KnowledgeInfo();
				dto2entity(dto, entity);
				knowledgeDAO.merge(entity);
			}
			// 删除备份数据.
			historyDataService.deleteHistoryData(historyDataNos);
		}
	}

	/**
	 * 获取登录用户的知识库分类权限
	 * @return List<Long>
	 */
	private List<Long> viewCategorys() {
		List<Long> viewCategorys = null;
		// 分类查看权限
		String loginUserName = appctx.getCurrentLoginName();
		Long[] views = userInfoService.findCategoryNosByLoginName(loginUserName,
				"Knowledge_Category_");

		if (views != null && views.length > 0) {
			viewCategorys = new ArrayList<Long>();
			for (Long l : views) {
				viewCategorys.add(l);
			}
		}
		return viewCategorys;
	}

	/**
	 * 分页全文检索.
	 * @param queryDTO
	 * @param page
	 * @param rows
	 * @return PageDTO
	 */
	@Transactional
	public PageDTO fullSearch(KnowledgeQueryDTO queryDTO, int start,int limit, String sidx, String sord) {
		fullTextSearch(queryDTO);
		PageDTO knowledges =new PageDTO();
		if(queryDTO.getKids()!=null && queryDTO.getKids().length>0)
			knowledges = findKnowledgesByPages(queryDTO, start,limit, sidx, sord);

		return knowledges;

	}

	/**
	 * 批量审核知识.
	 * 
	 * @param dto
	 */
	@Transactional
	public void passKW(KnowledgeDTO dto) {
		 
		LanguageContent lc = LanguageContent.getInstance();
		if (dto.getKids() != null && dto.getKids().length > 0) {
			//for (Long kid : dto.getKids()) {
			//for (int i = 0; i < dto.getKids().length; i++) {
				
				String desc = "";
				if ("creator".equals(dto.getKnowledgeAppDescRole())) {
					desc = lc.getContent("label.knowledge.passKWCreatorInfo")
							+ "：" + dto.getStatusDesc()
							+ "&nbsp;&nbsp;&nbsp;&nbsp;"
							+ lc.getContent("label.date") + "："
							+ TimeUtils.format(new Date(),TimeUtils.DATETIME_PATTERN);
				}else{
					desc = lc.getContent("label.knowledge.passKWAppInfo") + "："
							+ dto.getStatusDesc() + "&nbsp;&nbsp;&nbsp;&nbsp;"
							+ lc.getContent("label.date") + "："
							+ TimeUtils.format(new Date(),TimeUtils.DATETIME_PATTERN);
				}
				List<KnowledgeInfo> kw = knowledgeDAO.findByIds(dto.getKids());
				
				for (KnowledgeInfo knowledgeInfo : kw) {
					String statusDesc =knowledgeInfo.getStatusDesc() + "\r\n" + desc;
					knowledgeInfo.setStatusDesc(statusDesc);
					knowledgeInfo.setKnowledgeStatus(dto.getKnowledgeStatus());
					knowledgeInfo.setLastUpdateTime(new Date());
				}
				knowledgeDAO.mergeAll(kw);

			}
		//}
	}

	/**
	 * 按状态统计知识数量.
	 * @param flag 标识
	 * @return int
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public KnowledgeCountResultDTO countKnowledge(KnowledgeQueryDTO dto) {
		String loginUserName = "";
		if(!StringUtils.hasLength(dto.getLoginUserName())){
			loginUserName=appctx.getCurrentLoginName();
		}else{
			loginUserName=dto.getLoginUserName();
		}
//		if (dto.getOpt() != null&& (dto.getOpt().equals("my") || "myap".equals(dto.getOpt()) || "myapf".equals(dto.getOpt()))) {
//			dto.setCreatorName(loginUserName);
//		}
		if (dto.getEventId()!=null) {
			Long[] allSubCategoryIds = eventCategoryService.findSubCategoryIdsByEventId(dto.getEventId());
			Long[] ableCategoryIds = userInfoService.findCategoryNosByLoginName(loginUserName, "Knowledge_Category_");
			if(ableCategoryIds!=null){
				List<Long> categoryIds = (List<Long>) CollectionUtils.intersection(Arrays.asList(allSubCategoryIds), Arrays.asList(ableCategoryIds));
				//根据ID查看所有子节点
				dto.setEventIds(categoryIds.toArray(new Long[categoryIds.size()]));
			}else{
				//根据ID查看所有子节点
				dto.setEventIds(null);
			}
		}else{
			//设置查看权限(分类权限)
			dto.setEventIds(userInfoService.findCategoryNosByLoginName(loginUserName, "Knowledge_Category_"));
		}
		KnowledgeCountResultDTO kdto=new KnowledgeCountResultDTO();
		//共享知识
		dto.setOpt("share");
		kdto.setShareCount(knowledgeDAO.countChangeByType(dto));
		dto.setOpt(null);
		
		//我发布的知识
		dto.setOpt("my");
		dto.setCreatorName(loginUserName);
		kdto.setMyCount(knowledgeDAO.countChangeByType(dto));
		dto.setCreatorName(null);
		dto.setOpt(null);
		
	    //我的待审知识
		dto.setOpt("myap");
		dto.setCreatorName(loginUserName);
		kdto.setMyapCount(knowledgeDAO.countChangeByType(dto));
		dto.setCreatorName(null);
		dto.setOpt(null);
		
	    //所有待审知识
		dto.setOpt("allap");
		kdto.setAllapCount(knowledgeDAO.countChangeByType(dto));
		dto.setOpt(null);
		
	    //我未审核通过的知识
		dto.setOpt("myapf");
		dto.setCreatorName(loginUserName);
		kdto.setMyapfCount(knowledgeDAO.countChangeByType(dto));
		dto.setCreatorName(null);
		dto.setOpt(null);
		
	    //所有未审核通过的知识
		dto.setOpt("allapf");
		kdto.setAllapfCount(knowledgeDAO.countChangeByType(dto));
		dto.setOpt(null);
		
		return kdto;

	}

	/**
	 * 审核结果
	 * @param kid
	 * @return KnowledgeDTO
	 */
	public KnowledgeDTO appResult(Long kid) {
		KnowledgeDTO dto = new KnowledgeDTO();
		KnowledgeInfo entity = knowledgeDAO.findById(kid);
		dto.entity2dto(entity, dto);
		return dto;
	}
	/**
	 * 报表可链接查询返回值处理
	 * return pageDTO 转换好的数据
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public PageDTO findKnowledgesByCrosstabCell(KeyTransferDTO ktd, int start, int rows, String sidx, String sord){
		// 负责的所属客户
		Long[] companyNos = null;
		ktd.setEntityClass(ENTITYCLASS);
		ktd.setFilterCategory(FILTERCATEGORY);
		PageDTO pageDTO = linksEventQueryServices.finddynamic(ktd, companyNos, start, rows, sidx, sord);
		List<KnowledgeInfo> entitys=(List<KnowledgeInfo>) pageDTO.getData();
		List<KnowledgeDTO> dtos=new ArrayList<KnowledgeDTO>(entitys.size());
		for (KnowledgeInfo entity:entitys){
			KnowledgeDTO knowledgeDto=new KnowledgeDTO();
			if (entity.getCategory()!=null){
				knowledgeDto.setCategoryName(entity.getCategory().getEventName());
			}
			knowledgeDto.entity2dto(entity, knowledgeDto);
			List<EventCategory> ecs = entity.getServiceLists();
			if (ecs!=null&&ecs.size()>0){
				StringBuffer strBu = new StringBuffer();
				for (EventCategory ec:ecs){
					strBu.append(ec.getEventName() + ",");
				}
				String strName = strBu.toString();
				knowledgeDto.setKnowledgeServiceName(strName.substring(0,strName.length()-1));
			}
			dtos.add(knowledgeDto);
		}
		pageDTO.setData(dtos);
		return pageDTO;
	}
	
	/**
	 * 全文检索知识库的公共方法
	 */
	public void fullTextSearch(KnowledgeQueryDTO queryDTO ) {
		String[] multiFields=new String[]{"title","keyWords","content"};
		Long[] ids=LuenceUtil.getInstance(MODULECATEGORY).search(queryDTO.getAlias(), multiFields);
		queryDTO.setKids(ids);
		/*if(queryDTO.getCategoryIds() == null){//获取登录者能看到的分类
			Long[] ableCategoryIds = userInfoService.findCategoryNosByLoginName(appctx.getCurrentLoginName(), "Knowledge_Category_");
			queryDTO.setCategoryIds(ableCategoryIds);
		}*/
	}
	/**
	 * 重建知识库索引
	 * @return
	 */
	/*public void reindexKnowledgeInfo(){
		fullTextSearchService.index(KnowledgeInfo.class);
    }*/

	/**
	 * 根据某个属性查询知识
	 */
	public KnowledgeDTO findUniqueBy(String propertyName, Object value) {
		KnowledgeInfo entity = knowledgeDAO.findUniqueBy(propertyName, value);
		return entity == null ? null : new KnowledgeDTO();
	}
	
	@SuppressWarnings("unchecked")
	public List<CommentDTO> findByIdCommentKnowledge(Long kid){
		
		KnowledgeInfo knowledgeInfo=knowledgeDAO.findById(new Long(kid));
		List<CommentDTO> list=new ArrayList<CommentDTO>();
		sortClass sort = new sortClass();
		List<Comment> li=knowledgeInfo.getEvaluates();
        Collections.sort(li,sort);  
		for (Comment comment : li) {
			CommentDTO com=new CommentDTO();
			com.setRemark(comment.getRemark());
			com.setCreator(comment.getCreator());
			com.setCreateTime(comment.getCreateTime());
			com.setStars(comment.getStars());
			list.add(com);
		}
		return list;
	}
	
	class sortClass implements Comparator{
		@Override
		public int compare(Object o1, Object o2) {
			// TODO Auto-generated method stub
			Comment Comment0=(Comment)o1;
			Comment Comment1=(Comment)o2;
			 int flag = Comment1.getCreateTime().compareTo(Comment0.getCreateTime());  
			return flag;
		}
		
	}
	
	@Transactional
	public void saveStars(KnowledgeDTO dto){
		Comment comment=new Comment();
		comment.setRemark(dto.getRemark());
		comment.setStars(dto.getStars());
		comment.setCreator(dto.getCreator());
		comment.setType("knowledge");
		saveComment(comment);
		KnowledgeInfo info=knowledgeDAO.findById(dto.getKid());
		info.getEvaluates().add(comment);
		knowledgeDAO.merge(info);
	}
	
	@Transactional
	public void saveComment(Comment c){
		commentDAO.save(c);
	}

}